package com.eclipse.e20200131_模拟连接池.com.qf.app1.m4;

import java.lang.reflect.Field;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class JDBCUtils {

	// 1：获取一个logger对象，不能new，通过工厂方法来创建，可以传入一个名称
	// 2: 默认在路路径下加载log4j2.xml做为配置文件
	private static Logger logger = LogManager.getLogger("com.demo.qf.app1.m2.JDBCUtils");
	
	private static Logger logger1 = LogManager.getLogger("com.demo.qf.app1.m2.JDBCUtils");


	private static Properties config = new Properties();

	private static String diverclass = null;

	private static String url = null;

	private static String userName = null;

	private static String password = null;

	// 记载配置文件，读取jdbc的配置信息
	static {
		try {
			config.load(JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties"));
			url = config.getProperty("jdbc.url");
			userName = config.getProperty("jdbc.username");
			password = config.getProperty("jdbc.password");
			diverclass = config.getProperty("jdbc.diverclass");
		} catch (Exception ex) {
			ex.printStackTrace();
			logger.trace(ex+"123");
		}
	}

	/**
	 * 执行insert、update、delete
	 * 
	 * @param sql
	 * @param params
	 */
	public static void update(String sql, Object... params) {
		Connection connection = getConnection();

		PreparedStatement statement = null;
		try {
			statement = connection.prepareStatement(sql);

			for (int i = 0; i < params.length; i++) {
				statement.setObject(i + 1, params[i]);
			}

			statement.executeUpdate();
		} catch (SQLException ex) {
			throw new RuntimeException("执行的SQL有问题：" + sql, ex);
		} finally {
			closeResourec(connection, statement, null);
		}
	}

	/**
	 * 查询
	 * 
	 * @param sql
	 * @param clz
	 * @param params
	 * @return
	 */
	public static List select(String sql, Class clz, Object... params) {
		
		Connection connection = getConnection();
		System.out.println("123");
		PreparedStatement statement = null;
		try {
			
			statement = connection.prepareStatement(sql);

			for (int i = 0; i < params.length; i++) {
				statement.setObject(i + 1, params[i]);
			}
			
			ResultSet resultSet = statement.executeQuery();

			// 存放返回的结果，如：里面是Student对象
			List<Object> result = new ArrayList<>();
			Object object = null;
			Field[] fields = null;
			Object columnValue = null;
			while (resultSet.next()) {
				// 动态Student对象
				object = clz.newInstance();
				result.add(object);

				// 多态获取类的属性
				fields = clz.getDeclaredFields();

				// 遍历所有的属性，然后从结果集中获取同名的数据列的值
				for (Field field : fields) {
					columnValue = resultSet.getObject(field.getName());
					// 把数据库列的值放到Student对象中
					field.setAccessible(true);
					field.set(object, columnValue);
				}
			}
			return result;
		} catch (Exception ex) {
			throw new RuntimeException("执行的SQL有问题：" + sql, ex);
		} finally {
			closeResourec(connection, statement, null);
		}
	}

	/**
	 * 关闭资源
	 * 
	 * @param connection
	 * @param statement
	 * @param resultSet
	 */
	public static void closeResourec(Connection connection, Statement statement, ResultSet resultSet) {
		try {
			if (resultSet != null) {
				resultSet.close();
			}
			if (statement != null) {
				statement.close();
			}
			if (connection != null) {
				connection.close();
			}
		} catch (SQLException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 打开连接
	 * 
	 * @return
	 * @throws Exception
	 */
	public static Connection getConnection() {
		try {
			
			// 1:加载驱动类
			Class.forName(diverclass);
			System.out.println("456");
			// 2: 打开连接
			Connection connection = DriverManager.getConnection(url, userName, password);
			return connection;
		} catch (ClassNotFoundException ex) {
			throw new RuntimeException("数据库驱动没导入", ex);
		} catch (SQLException ex) {
			throw new RuntimeException("url或者用户名或者密码是错误", ex);
		}
	}
}
